package vn.njai.thousand_english_word.ChatHead;

import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.view.*;
import android.widget.*;
import butterknife.ButterKnife;
import butterknife.InjectView;
import vn.njai.thousand_english_word.Activity.MainActivity;
import vn.njai.thousand_english_word.Entities.NodeItem;
import vn.njai.thousand_english_word.R;
import vn.njai.thousand_english_word.Utils.DataManager;
import vn.njai.thousand_english_word.Utils.Utils;

import java.util.ArrayList;

/**
 * Created by VUONG on 12/22/2014.
 */
public class ChatHeadService extends Service {

    private WindowManager mWindowManager;
    private ImageView mHeadView;
    private ImageView mBackView;
    private ImageView mTrashView;
    private FrameLayout mListLayout;
    private WindowManager.LayoutParams mHeadParam = null;
    private WindowManager.LayoutParams mBackParam = null;
    private WindowManager.LayoutParams mTrashParam = null;
    private WindowManager.LayoutParams mListLayoutParam = null;
    private boolean mIsTrashShow = false;
    private ChatHeadService me = this;
    private boolean mIsTouch = false;
    private boolean mIsTouchBack = false;
    private ListView mSwipeListVIew;
    private ItemAdapter mAdapter;
    private ArrayList<Integer> mListColor;
    public static Context mContext;
    private int mDeltaX, mDeltaY;;

    @Override public IBinder onBind(Intent intent) {
        // Not used
        return null;
    }

    @Override public void onCreate() {
        super.onCreate();
        if(mContext == null)
            return;
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        initHeadListView();
        initTrashIcon();
        initHeadIcon();
        initBackIcon();

        mBackView.setOnTouchListener(new View.OnTouchListener() {
            private float initialTouchX;
            private float initialTouchY;
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mIsTouchBack = true;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        zoomBackIcon(20);
                        return true;
                    case MotionEvent.ACTION_UP:
                        if (mIsTouchBack) {
                            MainActivity.start(getBaseContext());
                        }
                        zoomBackIcon(-20);
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        mDeltaX = (int) (event.getRawX() - initialTouchX);
                        mDeltaY = (int) (event.getRawY() - initialTouchY);
                        if(mDeltaX > 10 || mDeltaY > 10 || mDeltaX < -10 || mDeltaY < -10){
                            mIsTouchBack = false;
                        }
                        return true;
                }
                return false;
            }
        });

        mHeadView.setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mIsTouch = true;
                        initialX = mHeadParam.x;
                        initialY = mHeadParam.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        zoomHeadIcon(20);
                        return true;
                    case MotionEvent.ACTION_UP:
                        if (mIsTouch) {
                            showHeadIconOnTop();
                        } else {
                            mIsTrashShow = false;
                            deleteHeadIcon();
                        }
                        zoomHeadIcon(-20);
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        mDeltaX = (int) (event.getRawX() - initialTouchX);
                        mDeltaY = (int) (event.getRawY() - initialTouchY);
                        if(mDeltaX > 10 || mDeltaY > 10 || mDeltaX < -10 || mDeltaY < -10){
                            mIsTouch = false;
                            if (mListLayout.getVisibility() == View.GONE) {
                                moveTrashIcon();
                            }
                        }
                        if (mListLayout.getVisibility() == View.GONE) {
                            mHeadParam.x = initialX + mDeltaX;
                            mHeadParam.y = initialY + mDeltaY;
                            mWindowManager.updateViewLayout(mHeadView, mHeadParam);
                        }
                        return true;
                }
                return false;
            }
        });

    }

    private void zoomHeadIcon(int delta){
        mHeadParam.width = mHeadView.getWidth() + delta;
        mHeadParam.height = mHeadView.getHeight() + delta;
        mWindowManager.updateViewLayout(mHeadView, mHeadParam);
    }

    private void zoomBackIcon(int delta){
        mBackParam.width = mBackView.getWidth() + delta;
        mBackParam.height = mBackView.getHeight() + delta;
        mWindowManager.updateViewLayout(mBackView, mBackParam);
    }

    private void moveTrashIcon(){
        if (mIsTrashShow == false) {
            mIsTrashShow = true;
            if (mTrashParam.x == 0) {
                mTrashParam.x = Utils.mScreenWeight / 2 - mTrashView.getWidth() / 2;
                mTrashParam.y = Utils.mScreenHeight - mTrashView.getHeight();
                mWindowManager.updateViewLayout(mTrashView, mTrashParam);
            }
            mTrashView.setVisibility(View.VISIBLE);
        }
    }

    private void deleteHeadIcon(){
        mTrashView.setVisibility(View.GONE);
        int w, h;
        w = mTrashView.getWidth();
        h = mTrashView.getHeight();
        if (mHeadParam.y > mTrashParam.y - h / 2 &&
                mHeadParam.x > mTrashParam.x - w / 2
                && mHeadParam.x < mTrashParam.x + w * 3 / 4
                && mHeadParam.y < mTrashParam.y + h) {
            me.stopSelf();
        } else
            moveToEdge(mHeadParam);
    }

    private void showHeadIconOnTop(){
        MoveAnimator moveAnimator = new MoveAnimator();
        moveAnimator.start(Utils.mScreenWeight - mHeadView.getWidth(), 0);
        mWindowManager.updateViewLayout(mHeadView, mHeadParam);
    }

    private void showHeadListView(){
        if (mListLayout.getVisibility() == View.GONE) {
            mListLayout.setVisibility(View.VISIBLE);
            mListLayoutParam.x = Utils.mScreenWeight / 2;
            mListLayoutParam.y = mHeadParam.y + mHeadView.getHeight();
            mWindowManager.updateViewLayout(mListLayout, mListLayoutParam);

            mBackView.setVisibility(View.VISIBLE);
            mBackParam.x = mHeadParam.x - mHeadView.getWidth() - 10;
            mBackParam.y = 0;
            mWindowManager.updateViewLayout(mBackView, mBackParam);
        } else {
            mListLayout.setVisibility(View.GONE);
            mBackView.setVisibility(View.GONE);
        }
        mIsTouch = false;
    }

    private void initTrashIcon(){
        mTrashView = new ImageView(this);
        mTrashView.setImageResource(R.drawable.ic_menu_exit);
        mTrashParam = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
        mTrashParam.gravity = Gravity.TOP | Gravity.LEFT;
        mTrashView.setVisibility(View.GONE);
        mWindowManager.addView(mTrashView, mTrashParam);
    }

    private void initBackIcon(){
        mBackView = new ImageView(this);
        mBackView.setImageResource(R.drawable.ic_back_head);
        mBackParam = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
        mBackParam.gravity = Gravity.TOP | Gravity.LEFT;
        mWindowManager.addView(mBackView, mBackParam);
        mBackView.setVisibility(View.GONE);
    }

    private void initHeadIcon(){
        mHeadView = new ImageView(this);
        mHeadView.setImageResource(R.drawable.ic_launcher);
        mHeadParam = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
        mHeadParam.gravity = Gravity.TOP | Gravity.LEFT;
        mHeadParam.x = 0;
        mHeadParam.y = 100;
        mWindowManager.addView(mHeadView, mHeadParam);
    }

    public void initHeadListView(){
        mListLayout = new FrameLayout(this);
        mListLayoutParam = new WindowManager.LayoutParams(
                Utils.mScreenWeight/2,
                Utils.mScreenHeight/2,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
        mListLayoutParam.gravity = Gravity.TOP | Gravity.LEFT;
        mListLayoutParam.x = 0;
        mListLayoutParam.y = 0;
        mListLayout.setVisibility(View.GONE);
        mListLayoutParam.gravity = Gravity.TOP | Gravity.LEFT;
        mWindowManager.addView(mListLayout,mListLayoutParam);

        LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        mSwipeListVIew = (ListView) li.inflate(R.layout.swipelistview,null);

        mListColor = new ArrayList<Integer>();
        mListColor.add(Color.rgb(77, 77, 77));
        mListColor.add(Color.rgb(47,177,171));
        mListColor.add(Color.rgb(124,150,59));
        mListColor.add(Color.rgb(241,106,112));
        mListColor.add(Color.rgb(193,106,20));

        mAdapter =new ItemAdapter();
        for(int i = 0;i< DataManager.getInstance().mLearning.mLearningList.size();i++){
            DataManager.getInstance().mLearning.mLearningList.get(i).mColor = mListColor.get(i);
        }
        mAdapter.addAll(DataManager.getInstance().mLearning.mLearningList);
        mSwipeListVIew.setAdapter(mAdapter);
        mSwipeListVIew.setAdapter(mAdapter);
        mListLayout.addView(mSwipeListVIew);
    }

    private void moveToEdge(WindowManager.LayoutParams params){
        MoveAnimator moveAnimator = new MoveAnimator();
        if(params.x + mHeadView.getWidth()/2 < Utils.mScreenWeight/2) {
            moveAnimator.start(0, params.y);
        }else{
            moveAnimator.start( Utils.mScreenWeight - mHeadView.getWidth(), params.y);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mHeadView != null) mWindowManager.removeView(mHeadView);
        if (mTrashView != null) mWindowManager.removeView(mTrashView);
        if (mListLayout != null) mWindowManager.removeView(mListLayout);
        if (mBackView != null) mWindowManager.removeView(mBackView);
    }

    private void move(float deltaX, float deltaY) {
        mHeadParam.x += deltaX;
        mHeadParam.y += deltaY;
        mWindowManager.updateViewLayout(mHeadView, mHeadParam);
    }

    private class MoveAnimator implements Runnable {

        private Handler handler = new Handler(Looper.getMainLooper());
        private float destinationX;
        private float destinationY;
        private long startingTime;

        private void start(float x, float y) {
            this.destinationX = x;
            this.destinationY = y;
            startingTime = System.currentTimeMillis();
            handler.post(this);
        }

        @Override
        public void run() {
            if (mHeadView != null && mHeadView.getParent() != null) {
                float progress = Math.min(1, (System.currentTimeMillis() - startingTime) / 400f);
                float deltaX = (destinationX - mHeadParam.x) * progress;
                float deltaY = (destinationY - mHeadParam.y) * progress;
                move(deltaX, deltaY);
                if (progress < 1) {
                    handler.post(this);
                }
                if(progress>=1 && mIsTouch == true) {
                    showHeadListView();
                }
            }
        }

        private void stop() {
            handler.removeCallbacks(this);
        }

    }

    public class ItemAdapter extends ArrayAdapter<NodeItem> {

        public ItemAdapter() {
            super(mContext, 0, new ArrayList<NodeItem>());
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            View view = convertView;
            final NodeItem item = getItem(position);

            if(view == null){
                LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
                view = inflater.inflate(R.layout.custom_node_main_small, parent, false);
                view.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, mListLayout.getHeight() / 5));
                holder = new ViewHolder(view);
                view.setTag(holder);
            }
            else{
                holder = (ViewHolder)view.getTag();
            }

            holder.imageBackground.setBackgroundColor(item.mColor);
            holder.txtWord.setText(item.mWord);
            holder.txtMeans.setText(item.mMeans);
            holder.txtPhonetic.setText(item.mPhonetic);
            holder.txtRank.setText(String.valueOf(item.mRank));
            holder.btnSound.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Handler handler = new Handler();
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                MediaPlayer mediaPlayer = new MediaPlayer();
                                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                                String url = "http://soundoftext.com/audio/English/" + item.mWord.toLowerCase() + ".mp3";
                                mediaPlayer.setDataSource(url);
                                mediaPlayer.prepare(); // might take long! (for buffering, etc)
                                mediaPlayer.start();
                            }catch (Exception ex){

                            }
                        }
                    });
                }
            });

            return view;
        }

        public class ViewHolder{
            @InjectView(R.id.imgBackground) public ImageView imageBackground;
            @InjectView(R.id.txtWord) public TextView txtWord;
            @InjectView(R.id.txtMeans) public TextView txtMeans;
            @InjectView(R.id.txtPhonetic) public TextView txtPhonetic;
            @InjectView(R.id.txtRank) public TextView txtRank;
            @InjectView(R.id.btnSound) public ImageButton btnSound;

            public ViewHolder(View view){
                ButterKnife.inject(this, view);
            }
        }

    }
}
